package com.bitoon.basketdudes.tuenti;

import com.bitoon.basketdudes.jpa.*;
import java.math.BigDecimal;
import java.util.Date;
import javax.persistence.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.*;

/**
 * @author paco 2012
 *
 * Login y registro de usuarios de Tuenti
 *
 */
public class TuLogin {

    protected EntityManagerFactory  m_emf = null;
    //protected EntityManager         m_em;
    protected Logger                m_log = Logger.getLogger(TuLogin.class);



    public TuLogin() {
        try {
            m_emf = PersistenceManager.getInstance().getEntityManagerFactory("jpa_basket");
        } catch (Exception e) {
            m_log.error("Error: ", e);
        }
    }

    /*
    public TuLogin( EntityManager p_em) {
        m_log.error( "CONSTRUCTOR MANAGER" );
        if ( p_em != null) {
            m_em = p_em;
        } else {
            m_em = getEntityManager();
        }
    }
     *
     */

    /*
    public EntityManager getEntityManager (  ) {
        try {
            if ( m_em == null) {
                
                //m_em  =  m_emf.createEntityManager(); // check 08.08.2012
            }
        } catch (Exception e) {
            m_log.error("[ERROR][constructor]: No se puedo conectar a la base de datos: " , e);
        }
        return m_em;
    }
     *
     */

    public String wsNewUser(HttpServletRequest request, HttpServletResponse response) {
        m_log.error( "CONSTRUCTOR" );

        String output = "" ;
        EntityManager em = null;
        try {
            int     p_tuenti_id   = Integer.parseInt(request.getParameter("tid"));
            String  p_nick        = request.getParameter("nick");
            String  cadena        = request.getParameter("passwd");
            

            m_log.error( "WS NEW USER "+p_tuenti_id + " " + p_nick + " pass:" + cadena );

            em = m_emf.createEntityManager(); // check 08.08.2012

            Usuario u = buscaUsuarioId( em, p_tuenti_id );
            if ( u != null) {
                // Ya existe el identificador del usuario
                output = "error=-50";
            } else {
                u = buscaUsuarioNick( em, p_nick );
                if ( u != null) {
                    // Ya existe el nick
                    output = "error=-51";
                } else {
                    em.getTransaction().begin();

                    u = new Usuario();
                    u.setNick(p_nick.toLowerCase());
                    u.setNickMostrar(p_nick);
                    u.setIdiomaId("ES");
                    u.setAdmin(0); 
                    u.setPassword(cadena);
                    u.setStatus(0);
                    u.setRobinson(2);
                    u.setReputacion(99);
                    u.setfAdmision(new Date());
                    u.setfAlta(new Date());
                    u.setfEula(new Date());
                    u.setGenero(0);

                    Pais pais = em.find(Pais.class, "ES");
                    if ( pais == null)
                        throw new ExcepcionGeneral( -100, "Pais no encontrado");
                    u.setPais( pais );
                    m_log.error("[guardando usuario XXX]: "+ u.getNick()+ " status "+ u.getStatus()+" reputacion"+u.getReputacion()+" pais"+u.getPais().getId());
                    em.persist(u);

                    output = "error=0" ;
                    em.getTransaction().commit();

                    em.getTransaction().begin();
                    Query q_nativa = em.createNativeQuery(
                    "update central.usuario set id = :id where lower(nick) = lower(:nick)");

                    q_nativa.setParameter ("id", p_tuenti_id);
                    q_nativa.setParameter ("nick", p_nick);

                    q_nativa.executeUpdate();
                    em.getTransaction().commit();
                }
            }
        } catch (Exception e) {
            m_log.error("[wsNewUser]: " , e);
            output = "error=-1";
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }
        return output;
    }

    // busca un usuario por su id y lo devuelve o bien devuelve null si no lo encuentra
    private Ingreso buscaIngresoClave ( EntityManager em, String p_clave ){
        try {
            Query q = em.createNamedQuery("Ingreso.findByClave");
            q.setParameter("clave", p_clave);
            return (Ingreso)q.getSingleResult();
        } catch (NoResultException nre) {
            return null;
        }
    }

    // busca un usuario por su id y lo devuelve o bien devuelve null si no lo encuentra
    private Bolsa buscaBolsaId ( EntityManager em, int p_id ){
        try {
            Query q = em.createNamedQuery("Bolsa.findById");
            q.setParameter("id", p_id);
            return (Bolsa)q.getSingleResult();
        } catch (NoResultException nre) {
            return null;
        }
    }

    // busca un usuario por su id y lo devuelve o bien devuelve null si no lo encuentra
    private Usuario buscaUsuarioId ( EntityManager em, int p_usuario_id ){
        try {
            Query q = em.createNamedQuery("Usuario.findById");
            q.setParameter("id", p_usuario_id);
            return (Usuario)q.getSingleResult();
        } catch (NoResultException nre) {
            return null;
        }
    }

    // busca un usuario por su nick y lo devuelve o bien devuelve  null si no lo encuentra
    private Usuario buscaUsuarioNick ( EntityManager em, String p_nick ){
        try {
            Query q = em.createNamedQuery("Usuario.findByNick");
            q.setParameter("nick", p_nick.toLowerCase() );
            return (Usuario)q.getSingleResult();
        } catch (NoResultException nre) {
            return null;
        }
    }

    public String consultarUsuarioId(HttpServletRequest request, HttpServletResponse response) {

        String          retorno = "";
        EntityManager   em = null;
        int             p_usuario_id=0;
        m_log.error("[INICIO2][consultarUsuarioId]: " );
        try {
            Usuario     u=null;
            em = m_emf.createEntityManager(); // check 07.08.2012

            if ( request.getParameter("id") == null ) {
                throw new ExcepcionGeneral( -11, "Incorrect parameters");
            }
            p_usuario_id = Integer.parseInt(request.getParameter("id"));

            Query q = em.createNamedQuery("Usuario.findById");
            q.setParameter("id", p_usuario_id );
            u = (Usuario)q.getSingleResult();
m_log.error("[UsuarioId]: "+p_usuario_id );
            retorno += "error=0;nick="+u.getNick()+";";
        } catch (NoResultException ex) {
            m_log.error("[ERROR][no existe]: " , ex);
            retorno = "error=-50";
        } catch (Exception x) {
            try { em.getTransaction().rollback(); } catch (Exception e2) { }
            m_log.error("[ERROR][ConsultarUsuarioId]: ", x);
            retorno = "error=-100";
        } finally {
            try { em.close(); } catch (Exception e)  // revisado 09/08/2012
            { m_log.error("[ERROR][constructor]: EMT base de datos: " , e); }
        }

        return retorno;
    }

    // Informa del precio de una bolsa de bitoones en tuenticreditos
    public String getItem(HttpServletRequest request, HttpServletResponse response) {

        String          retorno = "";
        EntityManager   em = null;
        int             p_item_id=0;

        try {
            Bolsa  u=null;
            em      = m_emf.createEntityManager(); // check 07.08.2012

            if ( request.getParameter("id") == null ) {
                throw new ExcepcionGeneral( -11, "Incorrect parameters");
            }
            p_item_id = Integer.parseInt(request.getParameter("id"));

            Query q = em.createNamedQuery("Bolsa.findById");
            q.setParameter("id", p_item_id );
            u = (Bolsa)q.getSingleResult();
m_log.debug("[GetItem itemId]: "+p_item_id );
            retorno += "error=0;precio="+u.getPrecio()+";bitoones="+u.getBitoones()+";";
        } catch (NoResultException ex) {
            m_log.error("[ERROR][no existe]: " , ex);
            retorno = "error=-50";
        } catch (Exception x) {
            try { em.getTransaction().rollback(); } catch (Exception e2) { }
            m_log.error("[ERROR][getItem]: ", x);
            retorno = "error=-100";
        } finally {
            try { if (em != null) em.close(); } // revisado 09/08/2012
            catch (Exception e) {
                m_log.error("[ERROR][constructor]: EMT base de datos: " , e);
            }
        }

        return retorno;
    }

    // Confirma una transacción de tuenticreditos por bitoones
    public String purchaseItem(HttpServletRequest request, HttpServletResponse response) {
        String salida="error=-1;";
        int p_user_id;
        int p_transaction_id;

        int p_item_id;
        int p_timestamp=0;
        String p_signature;
        EntityManager m_em = null;
m_log.debug("[INICIO purchaseItem]: ");

        try {
            m_em = m_emf.createEntityManager(); // check 07.08.2012
            if ( request.getParameter("user_id") == null ) {
                throw new ExcepcionGeneral( -11, "Incorrect parameters user_id");
            }
            p_user_id = Integer.parseInt(request.getParameter("user_id"));

            if ( request.getParameter("transaction_id") == null ) {
                throw new ExcepcionGeneral( -11, "Incorrect parameters transaction_id ");
            }
            p_transaction_id  = Integer.parseInt(request.getParameter("transaction_id"));

            if ( request.getParameter("item_id") == null ) {
                throw new ExcepcionGeneral( -11, "Incorrect parameters item_id");
            }
            p_item_id = Integer.parseInt(request.getParameter("item_id"));

            if ( request.getParameter("timestamp") == null ) {
                throw new ExcepcionGeneral( -11, "Incorrect parameters timestamp");
            }
            p_timestamp = Integer.parseInt(request.getParameter("timestamp"));

            if ( request.getParameter("signature") == null ) {
                throw new ExcepcionGeneral( -11, "Incorrect parameters signature");
            }
            p_signature = request.getParameter("signature");
m_log.debug("[user_id]: "+p_user_id+"[transaction_id]: "+p_transaction_id+"[item_id]: "+p_item_id+ "[p_timestamp]"+p_timestamp+"[p_signature]"+p_signature );

            m_em.getTransaction().begin();
            Usuario u = buscaUsuarioId( m_em, p_user_id );
            if ( u != null) {
                // Usuario existe

                // Buscamos el identificador de transacción si existe no volvemos a dar dinero
m_log.debug("buscamos la transacción por si existe ya");
                Ingreso ingreso = buscaIngresoClave ( m_em, request.getParameter("transaction_id") ) ;
                if ( ingreso != null)
                    throw new ExcepcionGeneral( -14, "Duplicated transaction");

                // Buscamos el identificador de bolsa para saber la cantidad que será asignada
                Bolsa bolsa = buscaBolsaId( m_em, p_item_id );
                if ( bolsa == null)
                    throw new ExcepcionGeneral( -13, "Incorrect item_id");

m_log.debug("guardamos ingreso");

                // Creamos un movimiento o ingreso ¿?
                ingreso = new Ingreso();
                ingreso.setEstado((short)0);
                ingreso.setFFin(new java.util.Date());
                ingreso.setFPeticion(new java.util.Date());
                ingreso.setBitoones(bolsa.getBitoones());
                ingreso.setClave( request.getParameter("transaction_id") );
                ingreso.setJuegoId((short)1); // basketdudes
                ingreso.setUsuarioId(p_user_id);
                ingreso.setMoneda("tweti");
                ingreso.setComision(BigDecimal.ZERO);
                ingreso.setImporte( BigDecimal.valueOf(bolsa.getPrecio()) );
                m_em.persist(ingreso);

m_log.debug("actualizamos credito usuario");
                // Asignamos el dinero al usuario
                u.setCreditos(u.getCreditos()+ingreso.getBitoones());

            } else {
                throw new ExcepcionGeneral( -12, "Incorrect user_id");
            }
            m_em.getTransaction().commit();
            salida = "error=0;bitoones="+u.getCreditos()+ ";";
        } catch (ExcepcionGeneral ex) {
            salida = "error="+ex.getCodigo()+";descripcion="+ex.getDescripion()+ ";";

        } catch (Exception e){
            salida = "error=-1;descripcion="+e.getLocalizedMessage()+ ";";
            m_log.error("[ERROR][getItem]: ", e);
            if (m_em     != null && m_em.getTransaction().isActive() )
                m_em.getTransaction().rollback();
        } finally {
            try { m_em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }


m_log.debug("[FIN purchaseItem]: "+ salida);
        return salida;
    }

}
